package ru.dc;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import ru.dc.object.CommandListener;
import ru.dc.object.HubEventListener;
import ru.dc.object.SearchRequest;
import ru.dc.object.UserInfo;
import ru.dc.object.commands.*;
import ru.dc.object.events.hub.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

/**
 * Created by IntelliJ IDEA.
 * User: deady
 * Date: 31.10.2010
 * Time: 12:50:29
 * To change this template use File | Settings | File Templates.
 */
public class HubEventsListener implements CommandListener{

    private Vector<HubEventListener> listeners = new Vector<HubEventListener>();
    private Log logger = LogFactory.getLog(getClass());

    public void commandRecieved(Command command) {

        if (!(command.getConnection() instanceof HubConnection)) {
            return;
        }

        HubConnection hubConnection = (HubConnection) command.getConnection();
        if (command instanceof Lock) {
            Lock lockCmd = (Lock) command;
            String lockStr = lockCmd.getLock();
            hubConnection.setKey(Lock.convertLockToKey(lockStr));

            if (lockCmd.isSupportsExtended()) {
                Supports supports = new Supports();
                supports.setFeatures("HubTopic NoGetINFO NoHello TTHSearch UserCommand UserIP2");
                command.getConnection().sendCommand(supports);
            }


            Key key = new Key();
            key.setKey(hubConnection.getKey());
            command.getConnection().sendCommand(key);

            ValidateNick validateNick = new ValidateNick();
            validateNick.setNick(command.getServerInfo().getNick());
            command.getConnection().sendCommand(validateNick);


        }

        else if (command instanceof Hello) {

            Hello hello = (Hello) command;
            if (command.getServerInfo().getNick().equals(hello.getNick())) {
                Version version = new Version();
                command.getConnection().sendCommand(version);

                command.getConnection().sendCommand(new GetNickList());

                MyINFO myINFO = new MyINFO();
                myINFO.setNick(command.getServerInfo().getNick());
                myINFO.setInterest("none");
                myINFO.setSpeed("DSL");
                myINFO.setEmail("qq@qq.qq");
                myINFO.setSharesize(1024L*1024*1024*10);
                command.getConnection().sendCommand(myINFO);

            }


        }

        else if (command instanceof ChatCommand) {
            ChatCommand cmd = (ChatCommand) command;
            if (listeners.size()>0) {
                ChatEvent e = new ChatEvent();
                e.setServerInfo(hubConnection.getServerInfo());
                e.setMessage(cmd.getText());
                e.setNick(cmd.getNick());
                fireHubEventOccured(e);
            }
            logger.debug("["+cmd.getNick()+"]: "+cmd.getText());
        }

        else if (command instanceof Quit) {
            Quit  cmd = (Quit) command;
            if (listeners.size()>0) {
                UserLeaved userLeaved = new UserLeaved();
                userLeaved.setServerInfo(hubConnection.getServerInfo());
                userLeaved.setNick(cmd.getNick());
                hubConnection.removeUser(cmd.getNick());

                fireHubEventOccured(userLeaved);
            }
            logger.debug("User "+cmd.getNick()+" logged out >>>");
        }

        else if (command instanceof MyINFO) {
            MyINFO myINFO = (MyINFO) command;
            if (listeners.size()>0) {
                UserEntered userEntered = new UserEntered();
                userEntered.setServerInfo(hubConnection.getServerInfo());
                UserInfo userInfo = new UserInfo();
                userInfo.setNick(myINFO.getNick());
                userInfo.setEmail(myINFO.getEmail());
                userInfo.setInterest(myINFO.getInterest());
                userInfo.setSharesize(myINFO.getSharesize());
                userInfo.setSpeed(myINFO.getSpeed());
                userEntered.setUserInfo(userInfo);
                hubConnection.addUser(userInfo);

                fireHubEventOccured(userEntered);
            }
            logger.debug("User "+myINFO.getNick()+" logged in <<<");
        }


        else if (command.getClass().equals(Command.class)) {
            logger.warn(command.getCommand());
        }

        else if (command instanceof HubName) {
            HubName hubName = (HubName) command;
            if (listeners.size()>0) {
                final HubNameRecieved changed = new HubNameRecieved();
                changed.setServerInfo(hubConnection.getServerInfo());
                changed.setName(hubName.getHubname());
                hubConnection.setName(hubName.getHubname());
                fireHubEventOccured(changed);
            }
            logger.debug("Name to "+hubName.getHubname());
        }

        else if (command instanceof HubTopic) {
            HubTopic hubTopic = (HubTopic) command;
            if (listeners.size()>0) {
                final TopicChanged changed = new TopicChanged();
                changed.setServerInfo(hubConnection.getServerInfo());
                changed.setTopic(hubTopic.getTopic());
                hubConnection.setTopic(hubTopic.getTopic());
                fireHubEventOccured(changed);
            }
            logger.debug("Topic changed to "+hubTopic.getTopic());
        }

        else if (command instanceof Search) {
            Search search = (Search) command;
            if (search.getDataType() != Search.SearchType.TTH) {
                logger.debug("Search: "+search.getSearchPattern());
            }

            SearchRequest request = new SearchRequest();
            request.setQuery(search.getSearchPattern());
            request.setSize(search.getSize());
            request.setDataType(search.getDataType());
            request.setMaxSize(search.isMaxSize());
            request.setSizeRestricted(search.isSizeRestricted());

            SearchRequestedEvent e = new SearchRequestedEvent();
            e.setServerInfo(hubConnection.getServerInfo());
            e.setRequest(request);
            fireHubEventOccured(e);

        }

        else if (command instanceof NickList) {
            NickList nickList = (NickList) command;
            if (listeners.size()>0) {
                RecievedNickList e = new RecievedNickList();
                e.setUsers(nickList.getUsers());
                e.setServerInfo(hubConnection.getServerInfo());
                fireHubEventOccured(e);
            }
            logger.debug("Recieved nick list: "+nickList.getUsers().length+" users");
        }

        else if (command instanceof UserIP) {
            UserIP userIP = (UserIP) command;
            String addr = userIP.getUserAddresses().get(hubConnection.getServerInfo().getNick());
            hubConnection.setAssignedAddress(addr);
            logger.debug("Assigned address: "+addr);
        }

        else if (command instanceof SR) {
            SR sr = (SR) command;
            if (listeners.size()>0) {

                SearchResultRecieved e = new SearchResultRecieved();
                e.setServerInfo(hubConnection.getServerInfo());
                e.setDirectory(sr.isDirectory());
                e.setFilename(sr.getFilename());
                e.setFreeSlots(sr.getFreeSlots());
                e.setTotalSlots(sr.getTotalSlots());
                e.setHubname(sr.getHubname());
                e.setHubIp(sr.getHubIp());
                e.setPort(sr.getPort());
                e.setTargetNick(sr.getTargetNick());
                e.setSourceNick(sr.getSourceNick());
                e.setServerInfo(sr.getServerInfo());
                e.setSize(sr.getSize());
                fireHubEventOccured(e);
            }
            logger.debug("Recieved search results: "+sr);
        }
        
        else if (command instanceof ConnectToMe) {
            ConnectToMe connectToMe = (ConnectToMe) command;
            ConnectionToClientRequested ev = new ConnectionToClientRequested();
            ev.setAddress(connectToMe.getAddress());
            ev.setPort(connectToMe.getPort());
            ev.setRemoteNick(connectToMe.getNick());
            ev.setServerInfo(connectToMe.getServerInfo());

            fireHubEventOccured(ev);
        }

        else if (command instanceof To) {
            To to = (To) command;
            PrivateMessageRecieved ev = new PrivateMessageRecieved();
            ev.setMessage(to.getMessage());
            ev.setSenderNick(to.getSenderNick());
            ev.setSourceNick(to.getSourceNick());
            ev.setTargetNick(to.getTargetNick());
            ev.setServerInfo(command.getServerInfo());

            fireHubEventOccured(ev);
        }
    }
    
    public void addEventListener(HubEventListener listener) {
        listeners.add(listener);
    }

    public void removeEventListener(HubEventListener listener) {
        listeners.remove(listener);
    }

    public void fireHubEventOccured(HubEvent e) {
        for (HubEventListener listener :  listeners) {
            listener.onEvent(e);
        }
    }


}
